
#include "VideoEncode.h"

void VideoEncode::Init(int width, int height, AVCodecContext* ctx)
{
	ci.codec = avcodec_find_encoder(AV_CODEC_ID_H264);
	ci.codecContext = avcodec_alloc_context3(ci.codec);
	if (!ci.codecContext) {
		fprintf(stderr, "Could not allocate video codec context\n");
		exit(1);
	}
	if (!ci.packet)
		exit(1);

	//int ret = avcodec_copy_context(ci.codecContext, ctx);
	/* put sample parameters */
	ci.codecContext->bit_rate = 4000000;

	ci.codecContext->time_base.num = 1;
	ci.codecContext->time_base.den = 15;
	ci.codecContext->framerate.den = 1;
	ci.codecContext->framerate.num = 15;
	//ci.codecContext->bit_rate = width * height * 1000;
	////ci.codecContext->bit_rate_tolerance = VBR;//width * height * 3;
	// resolution must be a multiple of two */
	ci.codecContext->width = width;
	ci.codecContext->height = height;
	ci.codecContext->coded_width = width;
	ci.codecContext->coded_height = height;
	ci.codecContext->gop_size = 20;
	ci.codecContext->max_b_frames = 1;
	ci.codecContext->pix_fmt = AV_PIX_FMT_YUV420P;
	ci.codecContext->sample_aspect_ratio = ctx->sample_aspect_ratio;
	ci.codecContext->pix_fmt = AV_PIX_FMT_YUV420P;
	ci.codecContext->codec = ci.codec;

	av_opt_set(ci.codecContext->priv_data, "tune", "zerolatency", 0);
	av_opt_set(ci.codecContext->priv_data, "preset", "veryfast", 0);
	/*AVDictionary *options = nullptr;
	av_dict_set(&options, "preset", "veryslow", 0);*/
	//av_dict_set(&options, "CRF", "0", 0);

	int ret = 0;
	ret = avcodec_open2(ci.codecContext, ci.codec, 0);// &options);
	if (ret < 0) {
		avError(ret);
		//	fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
		exit(1);
	}

	/*frame = av_frame_alloc();
	if (!frame) {
		fprintf(stderr, "Could not allocate video frame\n");
		exit(1);
	}
	frame->format = ci.codecContext->pix_fmt;
	frame->width = ci.codecContext->width;
	frame->height = ci.codecContext->height;*/
	
}

void VideoEncode::Encode(unsigned char* data, int size, AVPacket* &packet)
{

}

bool VideoEncode::Encode(AVFrame* fframe, AVPacket* &packet)
{
	/*int ret = av_frame_make_writable(fframe);
	if (ret < 0) {
		avError(ret);
		return false;
	}*/
	int ret;
	ret = avcodec_send_frame(ci.codecContext, fframe);
	if (ret < 0) {
		avError(ret);
		return false;
	}
	ret = avcodec_receive_packet(ci.codecContext, packet);
	return ret >= 0;
}

void VideoEncode::Release()
{
	avcodec_free_context(&ci.codecContext);
	av_packet_free(&ci.packet);
}
